package com.nononsenseapps.feeder.ui.feed

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.os.Build
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gitee.wsl.android.ext.math.dp
import com.google.android.material.elevation.ElevationOverlayProvider
import com.nononsenseapps.feeder.db.room.FeedItemDao
import com.nononsenseapps.feeder.db.view.PreviewItem
import com.nononsenseapps.feeder.ui.R
import com.nononsenseapps.feeder.ui.reader.sample.unicodeWrap
import com.nononsenseapps.feeder.util.DateUtils
import com.nononsenseapps.feeder.util.FeedViewListType
import com.nononsenseapps.feeder.util.naiveFindImageLinkList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class FeedItemListAdapterHelper (val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>, private val context: Context, private val itemDao: FeedItemDao, val viewModel:Boolean = false, private val actionCallback: ActionCallback){
    var reverseListOrder : Boolean=false
    var feedViewListType : FeedViewListType = FeedViewListType.NORMAL

    var expandable:Boolean = true
    var shadowAble:Boolean = false

    val overlayProvider = ElevationOverlayProvider(context);

    private val linkColor: Int =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            context.resources.getColor(R.color.accent, null)
        } else {
            @Suppress("DEPRECATION")
            context.resources.getColor(R.color.accent)
        }
    private val colorPrimary: Int =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            context.resources.getColor(R.color.window_background, null)
        } else {
            @Suppress("DEPRECATION")
            context.resources.getColor(R.color.window_background)
        }

    private val colorPrimaryDark: Int =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            context.resources.getColor(R.color.title_text_color, null)
        } else {
            @Suppress("DEPRECATION")
            context.resources.getColor(R.color.title_text_color)
        }

    fun getItemPosition(position: Int):Int{
        return if(reverseListOrder)  adapter.itemCount-position-1 else  position
    }

    fun getItemViewType(item: PreviewItem?, position: Int): Int {
        if (feedViewListType == FeedViewListType.PICTURE) {
            // Get item
            item?.let {
                if (item.imageUrl.isNullOrBlank()) {
                    if (item.plainSnippet.isNotBlank() && expandable) {
                        return FeedViewListType.EXPANDABLE.ordinal
                    }
                    return FeedViewListType.MINI.ordinal
                }
                //Timber.d("get view holder type image count:${item.image_count}")
                if (item.image_count > 2 && item.plainTitle.length < 50)//&& position%2==0
                    return FeedViewListType.MULTI_IMAGE.ordinal

                if (item.id % 3 == 0L)
                    return FeedViewListType.NORMAL.ordinal
                if (item.id % 4 == 0L) {
                    if (it.wordCount > 100) return FeedViewListType.CARD.ordinal
                    return FeedViewListType.PICTURE_UNDER.ordinal
                }
            }
        }
        return feedViewListType.ordinal
    }


   @SuppressLint("RestrictedApi")
   fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        //Timber.d("view holder type:%s \t\tfeedViewListType: %s",viewType,feedViewListType.name)
        val viewHolder: RecyclerView.ViewHolder =when(viewType){
            FeedViewListType.NORMAL.ordinal->  FeedItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_normal, parent, false), actionCallback,viewModel = viewModel)
            FeedViewListType.MINI.ordinal->  FeedItemHolder_Mini(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_mini, parent, false), actionCallback,viewModel = viewModel)
            FeedViewListType.PICTURE.ordinal-> FeedItemHolder_Big(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_big , parent, false), actionCallback,viewModel = viewModel)
            FeedViewListType.PICTURE_UNDER.ordinal-> FeedItemHolder_Big(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_big_under , parent, false), actionCallback,viewModel = viewModel)
            FeedViewListType.EXPANDABLE.ordinal->  FeedItemHolder_Expandable(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_expandable, parent, false), actionCallback,viewModel = viewModel)
            FeedViewListType.MULTI_IMAGE.ordinal->  FeedItemHolder_MultiImage(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_3_image, parent, false), actionCallback,viewModel = viewModel)
            FeedViewListType.CARD.ordinal->  FeedItemHolder_Card(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_card, parent, false), actionCallback,viewModel = viewModel)
            else -> FeedItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_story_item_normal, parent, false), actionCallback,viewModel = viewModel)
        }

        return viewHolder
    }


    fun onBindViewHolder(vHolder: RecyclerView.ViewHolder, position: Int,item: PreviewItem?) {
        when(vHolder){
            is FeedItemHolder->onBindViewHolder_Numal(vHolder,position,item)
            is FeedItemHolder_Big->onBindViewHolder_Big(vHolder,position,item)
            is FeedItemHolder_Expandable->onBindViewHolder_Expandable(vHolder,position,item)
            is FeedItemHolder_Mini->onBindViewHolder_Mini(vHolder,position,item)
            is FeedItemHolder_MultiImage->onBindViewHolder_MultImage(vHolder,position,item)
            is FeedItemHolder_Card->onBindViewHolder_Card(vHolder,position,item)
        }
    }


    fun onBindViewHolder_Numal(holder:FeedItemHolder, position: Int,item: PreviewItem?) {
        onBindViewHolder_Mini(holder,position,item)
    }

    fun onBindViewHolder_Card(holder:FeedItemHolder_Card, position: Int,item: PreviewItem?) {
        onBindViewHolder_Mini(holder,position,item)
    }

    fun onBindViewHolder_Big(holder:FeedItemHolder_Big, position: Int,item: PreviewItem?) {
        onBindViewHolder_Mini(holder,position,item)
    }

    fun onBindViewHolder_Expandable(holder:FeedItemHolder_Expandable, position: Int,item: PreviewItem?) {
        onBindViewHolder_Mini(holder,position,item)
    }

    fun onBindViewHolder_MultImage(holder:FeedItemHolder_MultiImage, position: Int,item: PreviewItem?) {
        // Make sure view is reset if it was dismissed
        holder.resetView()

        if(item==null)
            return

        holder.rssItem = item

        onBindViewHolder_Base(holder,item,position,adapter.itemCount)

        actionCallback.coroutineScope().launch(Dispatchers.IO) {
            itemDao.loadFeedItemContent(item.id)?.let {
                naiveFindImageLinkList(it).let{ urls->
                    actionCallback.coroutineScope().launch(Dispatchers.Main) {
                        urls?.size?.let { counts ->
                            when {
                                counts > 5 -> holder.imageView.setMaxSize(5)
                                counts > 3 -> holder.imageView.setMaxSize(3)
                                else -> holder.imageView.setMaxSize(counts)
                            }
                        }
                        holder.imageView.setImagesData(urls)
                    }
                }
            }
        }
        // Load image when item has been measured
        holder.itemView.viewTreeObserver.addOnPreDrawListener(holder)
    }

    fun onBindViewHolder_Mini(holder:FeedItemHolder_Mini, position: Int,item: PreviewItem?) {

        // Make sure view is reset if it was dismissed
        holder.resetView()

        if(item==null)
            return

        holder.rssItem = item

        onBindViewHolder_Base(holder,item,position,adapter.itemCount)

        if (item.imageUrl?.isNotEmpty() == true||item.enclosureLink?.isNotEmpty()==true) {
            // Take up width
            holder.imageView.visibility = View.VISIBLE
            // Load image when item has been measured
            holder.itemView.viewTreeObserver.addOnPreDrawListener(holder)
        } else {
            holder.imageView.visibility = View.GONE
        }
    }

    protected fun onBindViewHolder_Base(holder:AbstractFeedItemHolder, item: PreviewItem, position: Int, count:Int) {
        holder.authorTextView.visibility= View.INVISIBLE
        if(actionCallback.authorVisible()) {
            // Set the title first - must be wrapped in unicode marks so it displays correctly
            // with RTL
            val titleText = SpannableStringBuilder(context.unicodeWrap(item.feedDisplayTitle))
            // If no body, display domain of link to be opened
            if (holder.rssItem!!.plainSnippet.isEmpty()) {
                if (holder.rssItem!!.enclosureLink != null && holder.rssItem!!.enclosureFilename != null) {
                    titleText.append(context.unicodeWrap(" \u2014 ${holder.rssItem!!.enclosureFilename}"))
                } else if (holder.rssItem?.domain != null) {
                    titleText.append(context.unicodeWrap(" \u2014 ${holder.rssItem!!.domain}"))
                }

                if (titleText.length > item.feedDisplayTitle.length) {
                    titleText.setSpan(
                        ForegroundColorSpan(linkColor),
                        item.feedDisplayTitle.length + 3, titleText.length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
                }
            }
            holder.authorTextView.visibility= View.VISIBLE
            holder.authorTextView.text = titleText
            holder.loadFeedThumb(context)
        }else if((position+1)%10==0) {
            holder.authorTextView.visibility= View.VISIBLE
            holder.authorTextView.text = " $count-${position + 1} "
        }

        item.pubDate.let {
            if (it == null) {
                holder.dateTextView.visibility = View.GONE
            } else {
                holder.dateTextView.visibility = View.VISIBLE
                //holder.dateTextView.text = it.withZone(DateTimeZone.getDefault())
                //        .toString(shortDateTimeFormat)
                holder.dateTextView.text = DateUtils.timeAlong(it.toDate());
            }
        }

        holder.tags.text=when{
            item.wordCount >1000 -> " ... "
            item.wordCount >300 -> " .. "
            item.wordCount == 0 && item.link?.isNotEmpty() == true -> " link "
            item.link?.isEmpty() == true -> " memo "
            else -> " "
        }

        holder.fillTitle()
    }
}